//
//  HttpClient.swift
//  Wallet
//
//  Created by Julian on 2022/5/7.
//

import Foundation
import RxSwift

enum API: String {
    case currencies
    case liveRetas = "live_rates"
}

enum RequestError: Error {
    case pathNotFound(Int, String)  // 文件没找到
    case convertError(Int, String)  // 解析内容错误
    case decodeError(Int, String)  // 解析 Model 错误
}

/// Response 返回结构，T 为返回的成功数据
struct Response<T: Codable>: Codable {
    let ok: Bool
    let total: Int
    let data: T
}

final class HttpClient {
    func request<T: Codable>(_ type: T.Type, from path:API) -> Observable<T> {
        return Observable.create { observer in
            guard let sourcePath = self.getResourcePath(with: path.rawValue, fileExtension: "json") else {
                observer.onError(RequestError.pathNotFound(1003, "Could not found \(path.rawValue) file."))
                return Disposables.create()
            }
            guard let data = try? Data(contentsOf: sourcePath) else {
                observer.onError(RequestError.convertError(1002, "There was a problem decoding the data"))
                return Disposables.create()
            }
            
            do {
                let decoder = JSONDecoder()
                decoder.dateDecodingStrategy = .secondsSince1970
                let result = try decoder.decode(Response<T>.self, from: data)
                DispatchQueue.main.asyncAfter(deadline: .now()+1, execute: {
                    observer.onNext(result.data)
                })
            } catch {
                observer.onError(RequestError.decodeError(1001, "There was a problem decoding the data"))
            }
            return Disposables.create {
                // 此方法为模拟网络请求，真实场景则可在此处取消网络请求
                // request.cancel()
            }
        }
    }
    
    // 读取本地 json 文件
    func getResourcePath(with filename: String, fileExtension: String) -> URL? {
        return Bundle.main.url(forResource: filename, withExtension: fileExtension)
    }
}
